var Rx = require('rxjs');
var operators = require("rxjs/operators");
var SERVER_CONST = require("../server-const");
var express = require('express');
var router = express.Router();
var chatModel = require("../model/chatModel");
var collectionModel = require("../model/collectionModel");
var user = chatModel.user;
var channels = chatModel.channels;
var teams = chatModel.teams;
var channelMembers = chatModel.channelMembers;
var teamMembers = chatModel.teamMembers;
var util = require("../server-util/util");
var mongoose = require("mongoose");
const globalVar = require('../server-util/globalVar');
const {
	historyRouterType
} = require('../server-util/globalVar');
const {
	formatMsgContent
} = require('../server-util/util');
var post = chatModel.post;
var collectionItem = collectionModel.collectionItem;
router.get('/', util.checkAuth, function (req, res, next) {
	res.send('respond with a resource');
});
/**
 * @api {POST} /chat/DisbandedGroup 解散群
 * @apiParam (chat) {String} ChannelId
 * @apiSampleRequest off
 * @apiGroup chat
 */
router.post('/DisbandedGroup', util.checkAuth, function (req, res, next) {
	let ChannelId = mongoose.Types.ObjectId(req.body.ChannelId);
	new Rx.Observable(ob => {
		channels.remove({
			_id: {
				$eq: ChannelId
			}
		}).exec(function (err, result) {
			if (!err) {
				ob.next();
				ob.complete();
			} else {
				ob.error(err);
				ob.complete();
			}
		})
	}).pipe(
		operators.concatMap(cm => {
			return new Rx.Observable(ob => {
				channelMembers.find({
					ChannelId: {
						$eq: ChannelId
					}
				}).exec(function (err, result) {
					if (!err) {
						ob.next(result);
						ob.complete();
					} else {
						ob.error(err);
						ob.complete();
					}
				})
			})
		}),
		operators.concatMap(cm => {
			return new Rx.Observable(ob => {
				channelMembers.remove({
					ChannelId: {
						$eq: ChannelId
					}
				}).exec(function (err, result) {
					if (!err) {
						ob.next(cm);
						ob.complete();
					} else {
						ob.error(err);
						ob.complete();
					}
				})
			})
		}),
		operators.concatMap(cm => {
			return new Rx.Observable(ob => {
				post.remove({
					ChannelId: {
						$eq: ChannelId
					}
				}).exec(function (err, result) {
					if (!err) {
						ob.next(cm);
						ob.complete();
					} else {
						ob.error(err);
						ob.complete();
					}
				})
			})
		})
	).subscribe(subR => {
		util.res.success({
			res,
			data: subR.map(result => {
				return result._doc.UserId
			})
		});
	}, error => {
		util.res.error({
			res,
			msg: error
		});
	})
});
/**
 * @api {POST} /chat/updateGrouupInfo 更新群信息
 * @apiParam (chat) {String} ChannelId
 * @apiParam (chat) {String} DisplayName
 * @apiSampleRequest off
 * @apiGroup chat
 */
router.post('/updateGrouupInfo', util.checkAuth, function (req, res, next) {
	let ChannelId = mongoose.Types.ObjectId(req.body.ChannelId);
	let DisplayName = req.body.DisplayName;
	let Type = req.body.Type;
	channels.update({
		_id: ChannelId
	}, {
		$set: {
			DisplayName: DisplayName,
			Name: DisplayName,
			Type
		}
	}).exec(function (err, result) {
		if (!err) {
			util.res.success({
				res,
				data: result
			});
		}
	})
});
/**
 * @api {GET} /chat/getAllMyConcat 获取所有联系人
 * @apiParam (chat) {String} UserId=5e2c398bac12b72f306dc9fc
 * @apiSampleRequest off
 * @apiGroup chat
 */
router.get('/getAllMyConcat', util.checkAuth, function (req, res, next) {
	let UserId = mongoose.Types.ObjectId(req.query.UserId);
	teams.aggregate([{
			$match: {
				DisplayName: {
					$eq: 'default_team'
				}
			}
		}, {
			$lookup: {
				from: 'channels',
				localField: '_id',
				foreignField: 'TeamId',
				as: 'channels'
			}
		}, {
			$unwind: '$channels'
		}, {
			$lookup: {
				from: 'channelmembers',
				localField: 'channels._id',
				foreignField: 'ChannelId',
				as: 'members'
			}
		},
		{
			$match: {
				'members.UserId': {
					$in: [
						UserId
					]
				},

			}
		}, {
			$lookup: {
				from: 'users',
				as: 'users',

				pipeline: [{
					$match: {
						$expr: {
							$ne: ["$Username", ""],
							$ne: ["$Username", null]
						}
					}
				}]
			}
		},


		{
			$lookup: {
				from: 'files',
				localField: 'members.UserId',
				foreignField: 'UserId',
				as: 'files'
			}
		}, {
			$addFields: {
				members: {
					$map: {
						input: '$members',
						'in': {
							$mergeObjects: [{
									UserId: '$$this.UserId',
									MsgCount: '$$this.MsgCount',
									MentionCount: '$$this.MentionCount',
									AtMentionCount: '$$this.AtMentionCount',
								},
								{
									$arrayElemAt: [
										'$users',
										{
											$indexOfArray: [
												'$users._id',
												'$$this.UserId'
											]
										}
									]
								}
							]
						}
					}
				}
			}
		}, {
			$lookup: {
				from: 'posts',
				as: 'msgs',
				'let': {
					channelId: '$channels._id'
				},
				pipeline: [{
						$match: {
							$expr: {
								$eq: [
									'$$channelId',
									'$ChannelId'
								]
							}
						}
					},
					{
						$sort: {
							CreateAt: -1
						}
					},
					{
						$limit: 10
					},
					{
						$sort: {
							CreateAt: 1
						}
					}
				]
			}
		}, {
			$sort: {
				'msgs.CreateAt': -1
			}
		}, {
			$addFields: {
				posts: {
					$map: {
						input: '$msgs',
						'in': {
							$mergeObjects: [{
									PostId: '$$this._id',
									PostCreateAt: '$$this.CreateAt',
									PostUpdateAt: '$$this.UpdateAt',
									Message: '$$this.Message',
									ChannelId: '$$this.ChannelId',
									PostType: '$$this.Type',
									PostFileType: '$$this.FileType',
									FileDisplayName: '$$this.FileDisplayName',
									PreviewPath: '$$this.PreviewPath',
									FileSize: '$$this.FileSize',
									AtWhoList: '$$this.AtWhoList',
									Additional: '$$this.Additional',
								},
								{
									$arrayElemAt: [
										'$users',
										{
											$indexOfArray: [
												'$users._id',
												'$$this.UserId'
											]
										}
									]
								}
							]
						}
					}
				}
			}
		}, {
			$group: {
				_id: {
					_id: '$_id',
					DisplayName: '$DisplayName',
					Name: '$Name'
				},
				data: {
					$push: '$$ROOT'
				}
			}
		}, {
			$project: {
				_id: 0,
				team: '$_id',
				channels: {
					$map: {
						input: '$data',
						'in': {
							files: {
								$filter: {
									input: "$$this.files",
									as: "files",
									cond: {
										$eq: [
											"$$files.PostFileType",
											"avatar"
										]
									}
								},
							},
							files: {
								$map: {
									input: "$$this.files",
									as: "files",
									in: {
										UserId: "$$files.UserId",
										PreviewPath: "$$files.PreviewPath"
									}
								}
							},
							_id: '$$this.channels._id',
							DisplayName: '$$this.channels.DisplayName',
							Name: '$$this.channels.Name',
							CreateAt: '$$this.channels.CreateAt',
							TeamId: '$$this.channels.TeamId',
							Type: '$$this.channels.Type',
							CreatorId: '$$this.channels.CreatorId',
							my: {
								$filter: {
									input: '$$this.members',
									as: 'members',
									cond: {
										$eq: [
											'$$members.UserId',
											UserId
										]
									}
								}
							},
							members: {
								$map: {
									input: '$$this.members',
									as: 'members',
									'in': {
										_id: '$$members.UserId',
										Email: '$$members.Email',
										Username: '$$members.Username',
										Prefix: '$$members.Prefix',
										CreateAt: '$$members.CreateAt',
										MsgCount: '$$members.MsgCount',
										MentionCount: '$$members.MentionCount',
										AtMentionCount: '$$members.AtMentionCount',
										avatar: {
											$filter: {
												input: "$$this.files",
												as: "files",
												cond: {
													$and: [{
															$eq: [
																"$$files.UserId",
																"$$members.UserId"
															]
														},
														{
															$eq: [
																"$$files.PostFileType",
																"avatar"
															]
														}
													]
												}
											}
										},
									}
								}
							},
							posts: {
								$map: {
									input: '$$this.posts',
									as: 'posts',
									'in': {
										Type: '$$posts.PostType',
										FileType: '$$posts.PostFileType',
										PostId: '$$posts.PostId',
										CreateAt: '$$posts.PostCreateAt',
										UpdateAt: '$$posts.PostUpdateAt',
										UserId: '$$posts._id',
										ChannelId: '$$posts.ChannelId',
										Message: '$$posts.Message',
										Email: '$$posts.Email',
										Username: '$$posts.Username',
										Prefix: '$$posts.Prefix',
										FileDisplayName: '$$posts.FileDisplayName',
										PreviewPath: '$$posts.PreviewPath',
										FileSize: '$$posts.FileSize',
										AtWhoList: '$$posts.AtWhoList',
										Additional: '$$posts.Additional',
										avatar: {
											$filter: {
												input: "$$this.files",
												as: "files",
												cond: {
													$and: [{
															$eq: [
																"$$files.UserId",
																"$$posts._id"
															]
														},
														{
															$eq: [
																"$$files.PostFileType",
																"avatar"
															]
														}
													]
												}
											}
										},
									}
								}
							}
						}
					}
				}
			}
		}, {
			$project: {
				team: '$team',
				channels: {
					$map: {
						input: '$channels',
						as: 'channels',
						'in': {
							_id: '$$channels._id',
							DisplayName: '$$channels.DisplayName',
							Name: '$$channels.Name',
							CreateAt: '$$channels.CreateAt',
							TeamId: '$$channels.TeamId',
							members: '$$channels.members',
							posts: '$$channels.posts',
							Type: '$$channels.Type',
							CreatorId: '$$channels.CreatorId',
							MsgCount: {
								$arrayElemAt: [
									'$$channels.my',
									0
								]
							},
							MentionCount: {
								$arrayElemAt: [
									'$$channels.my',
									0
								]
							},
							AtMentionCount: {
								$arrayElemAt: [
									'$$channels.my',
									0
								]
							}
						}
					}
				}
			}
		}, {
			$project: {
				team: '$team',
				channels: {
					$map: {
						input: '$channels',
						as: 'channels',
						'in': {
							_id: '$$channels._id',
							ChannelId: '$$channels._id',
							DisplayName: '$$channels.DisplayName',
							Name: '$$channels.Name',
							CreateAt: '$$channels.CreateAt',
							TeamId: '$$channels.TeamId',
							members: '$$channels.members',
							posts: '$$channels.posts',
							MsgCount: '$$channels.MsgCount.MsgCount',
							MentionCount: '$$channels.MentionCount.MentionCount',
							AtMentionCount: '$$channels.AtMentionCount.AtMentionCount',
							Type: '$$channels.Type',
							CreatorId: '$$channels.CreatorId'
						}
					}
				}
			}
		}
	]).exec(function (err, result) {
		util.res.success({
			res,
			data: result[0]
		});
	});
});
/**
 * @api {POST} /chat/getTeamMembers 获取所有群组成员
 * @apiSampleRequest off
 * @apiGroup chat
 */
router.post("/getTeamMembers", util.checkAuth, function (req, res, next) {
	//let TeamId = mongoose.Types.ObjectId(req.body._id);
	teams.aggregate([{
			$match: {
				DisplayName: SERVER_CONST.DEFAULT_TEAM
			}
		},
		{
			$lookup: {
				from: "teammembers",
				localField: "_id",
				foreignField: "TeamId",
				as: "teammembers"
			}
		},
		{
			$project: {
				_id: 0,
				teammembers: "$teammembers"
			}
		},
		{
			$lookup: {
				from: "users",
				localField: "teammembers.UserId",
				foreignField: "_id",
				as: "userInfo"
			}
		},
		{
			$project: {
				users: "$userInfo"
			}
		}
	]).exec(function (err, result) {
		util.res.success({
			res,
			data: result[0].users
		});
	});
});
/**
 * @api {POST} /chat/searchChannel 搜索频道
 * @apiSampleRequest off
 * @apiParam (params) {Object} me={_id:5e2c398bac12b72f306dc9fc}
 * @apiParam (params) {Object} to={_id:5e2bea9aac12b72f306dc9f1}
 * @apiParam (params) {Object} team={_id:5e2be6cb1384fa2314f8faa4}
 * @apiGroup chat
 */
router.post("/searchChannel", util.checkAuth, function (req, res, next) {
	let data = req.body;
	let me = data.me;
	let meId = mongoose.Types.ObjectId(me._id);
	let to = data.to;
	let toId = mongoose.Types.ObjectId(to._id);
	let team = data.team;
	let TeamId = mongoose.Types.ObjectId(team._id);
	//私聊
	if ('Username' in to) {
		new Rx.Observable(ob => {
			util.findPrivateChatIsExist(meId, toId, function (fr) {
				if (!!fr) {
					ob.next(fr);
					ob.complete();
				} else {
					new channels({
						CreateAt: new Date().getTime(),
						TeamId,
						UpdateAt: null,
						DeleteAt: null,
						Type: "private",
						DisplayName: null,
						Name: null,
						Header: null,
						Purpose: null,
						LastPostAt: null,
						TotalMsgCount: null,
						ExtraUpdateAt: null,
						CreatorId: meId,
						SchemeId: null
					}).save(function (err, sr) {
						var newChannel = sr._doc;
						channelMembers.insertMany([{
								ChannelId: newChannel._id,
								UserId: meId,
								Roles: null,
								LastViewedAt: null,
								MsgCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
								MentionCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
								NotifyProps: null,
								LastUpdateAt: null,
								SchemeUser: null,
								SchemeAdmin: null,
							},
							{
								ChannelId: newChannel._id,
								UserId: toId,
								Roles: null,
								LastViewedAt: null,
								MsgCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
								MentionCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
								NotifyProps: null,
								LastUpdateAt: null,
								SchemeUser: null,
								SchemeAdmin: null,
							}
						], function (err, inserResult) {
							util.findPrivateChatIsExist(meId, toId, (fr) => {
								ob.next(fr);
								ob.complete();
							});
						});
					});
				}
			});
		}).subscribe(result => {
			channels.find({
				_id: result._id
			}, function (err, fr) {
				util.res.success({
					res,
					data: {
						userIds: [
							meId,
							toId
						],
						ChannelId: result._id
					}
				});
			});
		});
		//群聊
	} else {
		channelMembers.findOne({
			UserId: meId,
			ChannelId: toId
		}).exec(function (err, result) {
			if (!!result && !!result._doc) {
				util.res.success({
					res,
					data: {
						userIds: [
							meId
						],
						ChannelId: toId
					}
				});
			} else {
				channelMembers.insertMany([{
					ChannelId: toId,
					UserId: meId,
					Roles: null,
					LastViewedAt: null,
					MsgCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
					MentionCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
					NotifyProps: null,
					LastUpdateAt: null,
					SchemeUser: null,
					SchemeAdmin: null,
				}, ], function (err, insertResult) {
					if (!err) {
						util.res.success({
							res,
							data: {
								userIds: [
									meId
								],
								ChannelId: toId
							}
						});
					}
				})
			}
		})
	}
});
/**
 * @api {POST} /chat/getRecentAtWhoMsgList 获取最近的atMe消息
 * @apiSampleRequest off
 * @apiParam (params) {String} earliestCreateAt 消息列表里面的最早的一条消息
 * @apiParam (params) {String} ChannelId
 * @apiParam (params) {String} limit
 * @apiGroup chat
 */
router.post("/getRecentAtWhoMsgList", util.checkAuth, async function (req, res, next) {
	let earliestCreateAt = req.body.earliestCreateAt;
	let ChannelId = mongoose.Types.ObjectId(req.body.ChannelId);
	let UserId = req.body.UserId;
	let limit = req.body.limit;
	/* 异步赋值 */
	let result = await post.aggregate([{
			$match: {
				/* 含 AtWhoList 并且 _id 含UserId*/
				AtWhoList: {
					$elemMatch: {
						"_id": UserId
					}
				},
				CreateAt: {
					/*日期 范围要早于 earliestCreateAt*/
					$lte: earliestCreateAt
				}
			}
		},
		/* 日期倒序,取最近的那一条 */
		{
			$sort: {
				CreateAt: -1
			}
		},
		/* 取一条 */
		{

			$limit: 1
		}

	])

	if (result && Array.isArray(result) && result.length > 0) {
		// let recentAtMsgPostId = result[0]._id
		let CreateAt = result[0].CreateAt
		let recentAtMsgs = await post.aggregate([{
				$match: {
					/* 取CreateAt范围 */
					CreateAt: {
						/* 日期早于 */
						$lt: earliestCreateAt,
						/* 日期大于或者等于 */
						$gte: CreateAt
					},
					ChannelId: ChannelId
				}
			},

			{
				$lookup: {
					from: 'users',
					as: "users",
					let: {
						userId: "$UserId"
					},
					pipeline: [{
						$match: {
							$expr: {
								$eq: [
									"$$userId",
									"$_id"
								]
							}
						}
					}]
				}
			},
			{
				$lookup: {
					from: 'files',
					localField: 'users._id',
					foreignField: 'UserId',
					as: 'files'
				}
			},
			{
				$unwind: {
					path: "$users"
				}
			},
			{
				$project: {
					AtWhoList: "$AtWhoList",
					Additional: "$Additional",
					ChannelId: "$ChannelId",
					CreateAt: "$CreateAt",
					Email: "$users.Email",
					Message: "$Message",
					PostId: "$_id",
					Prefix: "$users.Prefix",
					UpdateAt: "$UpdateAt",
					Type: "$Type",
					UserId: "$users._id",
					Username: "$users.Username",
					avatar: {
						$filter: {
							input: "$files",
							as: "files",
							cond: {
								$and: [{
										$eq: [
											"$$files.UserId",
											"$users._id"
										]
									},
									{
										$eq: [
											"$$files.PostFileType",
											"avatar"
										]
									}
								]
							}
						}
					}
				}
			}
		])

		util.res.success({
			res,
			data: recentAtMsgs
		});

	} else {
		util.res.error({
			res,
			msg: "找不到对应的消息"
		});
	}



})



/**
 * @api {POST} /chat/getHistoryMsgs 历史消息
 * @apiSampleRequest off
 * @apiParam (params) {String} CreateAt
 * @apiParam (params) {String} ChannelId
 * @apiParam (params) {String} limit
 * @apiGroup chat
 */
router.post("/getHistoryMsgs", util.checkAuth, function (req, res, next) {
	let CreateAt = req.body.CreateAt;
	let ChannelId = mongoose.Types.ObjectId(req.body.ChannelId);
	let limit = req.body.limit;
	let _historyRouterType = req.body.historyRouterType;
	let _PostId = req.body.PostId ? mongoose.Types.ObjectId(req.body.PostId) : false;




	//向上滚动获取数据，或者普通的取历史消息
	if (!_historyRouterType || _historyRouterType == historyRouterType.UP_GET_HISTORY_MSG) {
		post.aggregate([{
				$match: {
					ChannelId,
					CreateAt: {
						$lt: CreateAt
					}
				}
			},
			{
				$sort: {
					CreateAt: -1
				}
			},
			{
				$limit: limit
			},
			{
				$sort: {
					CreateAt: 1
				}
			},
			...formatMsgContent()
		]).exec(function (err, result) {
			util.res.success({
				res,
				data: result
			});
		});

	}
	//向下滚动获取数据，或者普通的取历史消息
	else if (!_historyRouterType || _historyRouterType == historyRouterType.DOWN_GET_HISTORY_MSG) {
		post.aggregate([{
				$match: {
					ChannelId,
					CreateAt: {
						$gt: CreateAt
					}
				}
			},
			{
				$sort: {
					CreateAt: 1
				}
			},
			{
				$limit: limit
			},
			{
				$sort: {
					CreateAt: -1
				}
			},
			...formatMsgContent()
		]).exec(function (err, result) {
			util.res.success({
				res,
				data: result
			});
		});
	}
	//从收藏跳过去获取历史消息
	else if (_PostId && _historyRouterType == historyRouterType.JUMP_TO_HISTORY_MSG) {


		let prev = new Promise((resolve, reject) => {
			post.aggregate([{
					$match: {
						ChannelId,
						_id: {
							$lte: _PostId
						}
					}
				},
				//sort和next的sort相反
				{
					$sort: {
						CreateAt: -1
					}
				},
				{
					$limit: limit
				},
				//sort和next的sort相反
				{
					$sort: {
						CreateAt: 1
					}
				},
				...formatMsgContent()
			]).exec(function (err, result) {
				if (err) {
					reject(err)
				} else {
					resolve(result)
				}

			});
		})
		let next = new Promise((resolve, reject) => {
			post.aggregate([{
					$match: {
						ChannelId,
						_id: {
							$gt: _PostId
						}
					}
				},
				//sort和prev的sort相反
				{
					$sort: {
						CreateAt: 1
					}
				},
				{
					$limit: limit
				},
				//sort和prev的sort相反
				{
					$sort: {
						CreateAt: -1
					}
				},
				...formatMsgContent()
			]).exec(function (err, result) {
				/* util.res.success({
					res,
					data: result
				}); */

				if (err) {
					reject(err)
				} else {
					resolve(result)
				}


			});
		})

		Promise.all([prev, next]).then((arr) => {
			util.res.success({
				res,
				data: [...arr[1], ...arr[0]]
			})

		})


	}

});
/**
 * @api {POST} /chat/addMembersToGroup 添加群成员
 * @apiSampleRequest off
 * @apiParam (params) {String} ChannelId
 * @apiParam (params) {Array} memberIDS
 * @apiGroup chat
 */
router.post("/addMembersToGroup", util.checkAuth, function (req, res, next) {
	let ChannelId = mongoose.Types.ObjectId(req.body.ChannelId);
	let memberIDS = req.body.memberIDS.map((id) => {
		return mongoose.Types.ObjectId(id);
	});
	if (memberIDS.length < 1) {
		util.res.error({
			res,
			msg: "没有选择群成员"
		});
	} else {
		channelMembers.insertMany(memberIDS.map(m => {
			return {
				ChannelId: ChannelId,
				UserId: m,
				Roles: null,
				LastViewedAt: null,
				MsgCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
				MentionCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
				NotifyProps: null,
				LastUpdateAt: null,
				SchemeUser: null,
				SchemeAdmin: null,
			}
		}), function (err, inserResult) {
			util.res.success({
				res,
				data: inserResult
			})
		});
	}
});
/**
 * @api {POST} /chat/getGroupMembers 获取群成员
 * @apiSampleRequest off
 * @apiParam (params) {String} ChannelId
 * @apiGroup chat
 */
router.post("/getGroupMembers", util.checkAuth, function (req, res, next) {
	let ChannelId = mongoose.Types.ObjectId(req.body.ChannelId);
	channelMembers.aggregate([{
			'$match': {
				'ChannelId': ChannelId
			}
		},
		{
			'$project': {
				'UserId': '$UserId',
				'_id': 0
			}
		},
		{
			'$lookup': {
				'from': 'users',
				'localField': 'UserId',
				'foreignField': '_id',
				'as': 'users'
			}
		},
		{
			'$unwind': {
				'path': '$users'
			}
		},
		{
			'$project': {
				'users': '$users'
			}
		},
		{
			'$replaceRoot': {
				'newRoot': '$users'
			}
		},
		{
			$lookup: {
				from: 'files',
				localField: '_id',
				foreignField: 'UserId',
				as: 'files'
			}
		},
		{
			'$project': {
				'Email': '$Email',
				'Username': '$Username',
				'Prefix': '$Prefix',
				'Phone': '$Phone',
				'CreateAt': '$CreateAt',
				'Nickname': '$Nickname',
				'FirstName': '$FirstName',
				'LastName': '$LastName',
				'Roles': '$Roles',
				'avatar': {
					$filter: {
						input: "$files",
						as: "files",
						cond: {
							$and: [{
								$eq: ["$$files.UserId", "$_id"],
								$eq: ["$$files.PostFileType", "avatar"]
							}]
						}
					}
				}
			}
		}
	]).exec(function (err, result) {
		if (!err) {
			util.res.success({
				res,
				data: result
			})
		}
	})
});
/**
 * @api {POST} /chat/createGroup 创建群聊
 * @apiSampleRequest off
 * @apiParam (params) {String} DisplayName
 * @apiParam (params) {Array} memberIDS
 * @apiParam (params) {String} CreatorId
 * @apiParam (params) {String} TeamId
 * @apiParam (params) {String} type
 * @apiGroup chat
 */
router.post("/createGroup", util.checkAuth, function (req, res, next) {
	let DisplayName = req.body.DisplayName;
	let memberIDS = req.body.memberIDS.map((id) => {
		return mongoose.Types.ObjectId(id);
	});
	let CreatorId = mongoose.Types.ObjectId(req.body.CreatorId);
	memberIDS.push(CreatorId); //把自己加上去
	let TeamId = mongoose.Types.ObjectId(req.body.TeamId);
	let type = req.body.type;
	if (memberIDS.length < 1) {
		util.res.error({
			res,
			msg: "没有选择群成员"
		});
	} else {
		new Rx.Observable(ob => {
			channels.find({
				DisplayName
			}).exec(function (err, result) {
				if (result.length > 0) {
					ob.next(false)
				} else {
					ob.next(true);
				}
			})
		}).pipe(
			operators.concatMap(cm => {
				return new Rx.Observable(ob => {
					if (cm) {
						new channels({
							DisplayName: DisplayName,
							Name: DisplayName,
							CreateAt: new Date().getTime(),
							TeamId: TeamId,
							UpdateAt: null,
							DeleteAt: null,
							Type: type,
							Header: null,
							Purpose: null,
							LastPostAt: null,
							TotalMsgCount: null,
							ExtraUpdateAt: null,
							CreatorId: CreatorId,
							SchemeId: null
						}).save(function (s_error, s_result) {
							if (!s_error) {
								ob.next(s_result);
								ob.complete();
							}
						})
					} else {
						ob.error('群名称重复,请重新输入');
						ob.complete();
					}
				})
			}),
			operators.concatMap(cm => {
				return new Rx.Observable(ob => {
					channelMembers.insertMany(memberIDS.map(m => {
						return {
							ChannelId: cm._id,
							UserId: m,
							Roles: null,
							LastViewedAt: null,
							MsgCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
							MentionCount: 0, //注意这里是自增字段,要给他赋予初始值为0,不能是null,如果为null,无法自增.
							NotifyProps: null,
							LastUpdateAt: null,
							SchemeUser: null,
							SchemeAdmin: null,
						}
					}), function (err, inserResult) {
						if (!err) {
							ob.next({
								ChannelId: cm._id,
								userIds: inserResult.map((item) => {
									return item.UserId
								})
							});
							ob.complete();
						}
					});
				})
			})
		).subscribe((resResult) => {
			util.res.success({
				res,
				data: resResult
			})
		}, error => {
			util.res.error({
				res,
				msg: error
			});
		})
	}
});
/**
 * @api {DELETE} /chat/removeMembers 移除群组成员
 * @apiSampleRequest off
 * @apiParam (params) {String} UserId
 * @apiParam (params) {String} ChannelId
 * @apiGroup chat
 */
router.delete("/removeMembers", util.checkAuth, function (req, res, next) {
	let UserId = mongoose.Types.ObjectId(req.param('UserId'));
	let ChannelId = mongoose.Types.ObjectId(req.param('ChannelId'));
	channelMembers.deleteOne({
		UserId,
		ChannelId
	}).exec(function (err, result) {
		if (!err) {
			util.res.success({
				res,
				data: result
			});
		}
	});
});
/**
 * @api {get} /chat/searchMsgByStr 关键字查找聊天记录
 * @apiSampleRequest off
 * @apiParam (params) {String} UserId
 * @apiParam (params) {String} str
 * @apiGroup chat
 */
router.get("/searchMsgByStr", util.checkAuth, function (req, res, next) {
	let UserId = mongoose.Types.ObjectId(req.query.UserId);
	let str = req.query.str;
	channelMembers.aggregate([{
		$match: {
			UserId: {
				$eq: UserId
			}
		}
	}, {
		$lookup: {
			from: 'channels',
			localField: 'ChannelId',
			foreignField: '_id',
			as: 'channels'
		}
	}, {
		$unwind: {
			path: "$channels"
		}
	}, {
		$project: {
			_id: 0,
			ChannelId: "$ChannelId",
			UserId: "$UserId",
			DisplayName: "$channels.DisplayName",
			Type: "$channels.Type"
		}
	}, {
		$group: {
			_id: '$ChannelId',
			data: {
				$push: "$$ROOT"
			}
		}
	}, {
		$unwind: {
			path: "$data"
		}
	}, {
		$replaceRoot: {
			newRoot: "$data"
		}
	}, {
		$lookup: {
			from: 'posts',
			as: "posts",
			let: {
				channelid: "$ChannelId"
			},
			pipeline: [{
				$match: {
					$expr: {
						$and: [{
								$eq: ["$ChannelId", "$$channelid"]
							},
							{
								$eq: ["$Type", "str"] //之拿文本消息
							}
						]
					},
					Message: {
						$regex: new RegExp(str),
						$options: "i"
					}
				}
			}]
		}
	}, {
		$unwind: {
			path: "$posts"
		}
	}, {
		$project: {
			ChannelId: "$ChannelId",
			DisplayName: "$DisplayName",
			UserId: "$posts.UserId",
			Message: "$posts.Message",
			MessageCreateAt: "$posts.CreateAt",
			Type: "$Type",
			PostId: "$posts._id"
		}
	}, {
		$lookup: {
			from: 'users',
			localField: 'UserId',
			foreignField: '_id',
			as: 'users'
		}
	}, {
		$unwind: {
			path: "$users"
		}
	}, {
		$project: {
			ChannelId: "$ChannelId",
			DisplayName: "$DisplayName",
			UserId: "$UserId",
			Message: "$Message",
			MessageCreateAt: "$MessageCreateAt",
			Type: "$Type",
			Username: "$users.Username",
			PostId: "$PostId"
		}
	}]).exec(function (err, result) {
		util.res.success({
			res,
			data: result
		});
	})
});


router.post('/updatePost2', util.checkAuth, function (req, res, next) {
	//消息id
	let PostId = mongoose.Types.ObjectId(req.body.PostId);
	//该更新类型的创建者id，例如更新收藏消息，则是点击收藏的时候那个人的id，也就是当前登录人的id，注意不是标签创建者的id
	let FieldCreatorId = req.body.FieldCreatorId;
	//更新类型，有标签收藏，表情等
	let FieldKey = req.body.FieldKey;
	//更新后的值,注意，这里是整个类型的值的集合，整个数组，例如标签，则是整个MsgCollection对应的集合
	let FieldValue = req.body.FieldValue;
	//当前更新的时间
	let now = util.generateNow()

	post.aggregate([

		{
			$match: {
				_id: PostId
			}
		}
	]).exec((err, result) => {


		//如果有，则更新
		let isUpdate = false
		if (!result[0]['Additional']) {
			result[0]['Additional'] = {}
		}
		if (!result[0]['Additional'][FieldKey]) {
			result[0]['Additional'][FieldKey] = []
		}
		if (result[0]['Additional'][FieldKey] && Array.isArray(result[0]['Additional'][FieldKey])) {}


		//看collectionArr是不是空数组，如果空数组，直接剔除该FieldKey里面的数据
		let isEmptyCollectionArr = false

		//统一只更新 Additional 里面包括的各种附加属性，例如MsgCollection,MsgEmoji
		let Additional = result[0]['Additional']

		Additional[FieldKey] = Additional[FieldKey].map(res => {
			//如果有则是更新
			if (res.Creator._id == FieldCreatorId) {
				isUpdate = true
				//将传过来的对应的CretorId的，跟库里的交换
				let target = FieldValue.find(r => {
					return r.Creator._id == FieldCreatorId
				})


				//collectionArr注意这个，不是单单指收藏，所有的类型都用这个数组

				if (target.collectionArr.length < 1) {
					isEmptyCollectionArr = true
				}

				res = target
			}
			return res
		})

		if (isEmptyCollectionArr) {
			Additional[FieldKey] = Additional[FieldKey].filter(res => {
				return res.Creator._id != FieldCreatorId
			})
		}

		//如果没有则push进去,isEmptyCollectionArr为false的时候，不会进这里
		if (!isUpdate) {
			Additional[FieldKey].push(FieldValue.find(r => {
				return r.Creator._id == FieldCreatorId
			}))
		}

		//进行更新操作
		post.updateOne({
			_id: PostId
		}, {
			$set: {
				Additional
			}
		}, {
			"upsert": true
		}).exec((err, result) => {

			if (err) {
				util.res.error({
					res,
					msg: "服务器报错",
				});
			} else {

				post.aggregate([

					{

						$match: {
							_id: PostId
						}
					}
				]).exec((err, result) => {

					if (err) {
						util.res.error({
							res,
							msg: "服务器报错",
						});
					} else {
						util.res.success({
							res,
							data: result,
						});
					}

				})



			}

		})
	})

})






module.exports = router;
